﻿using System;
using System.Reactive.Linq;
using System.ComponentModel.Composition;
using System.Windows.Input;
using ZOIL.Library.Behaviors;

namespace ZOIL.Library.Behaviors
{
    [Export(typeof(PluginSelectionBehavior))]
    public class MouseSelectionBehavior : PluginSelectionBehavior
    {
        #region private fields

        private IDisposable _mouseSelectionSubscription;

        #endregion

        #region private methods

        private IDisposable RegisterMouseEvents()
        {
            var mouseMove = Observable.FromEventPattern<MouseEventArgs>(AssociatedObject, "MouseMove").Where(evt => !evt.EventArgs.IsTouchOrigin());

            var mouseLeftButtonDown = Observable.FromEventPattern<MouseButtonEventArgs>(AssociatedObject, "MouseLeftButtonDown").Where(evt => !evt.EventArgs.IsTouchOrigin());

            var mouseLeftButtonUp = Observable.FromEventPattern<MouseButtonEventArgs>(AssociatedObject, "MouseLeftButtonUp").Where(evt => !evt.EventArgs.IsTouchOrigin());

            var mouseMoves = from mm in mouseMove
                             select mm.EventArgs.GetPosition(null);

            var mouseDrag = from mlbd in mouseLeftButtonDown.Select(evt => new Selection(evt.EventArgs.GetPosition(null))).Do(s => { StartSelection(s); Mouse.Capture(AssociatedObject); })
                            from md in mouseMoves.Do(point => mlbd.Points.Add(point)).TakeUntil(mouseLeftButtonUp.Do(evt => mlbd.Points.Add(evt.EventArgs.GetPosition(null))).Do(evt => { FinishSelection(mlbd); AssociatedObject.ReleaseMouseCapture(); }))
                            select mlbd;

            return mouseDrag.Subscribe(ChangeSelection);
        }

        #endregion

        #region overrides

        protected override void OnIsEnabledChanged(bool oldIsSelectionEnabled, bool newIsSelectionEnabled)
        {
            if (newIsSelectionEnabled)
            {
                _mouseSelectionSubscription = RegisterMouseEvents();
            }
            else
            {
                if (_mouseSelectionSubscription != null)
                {
                    _mouseSelectionSubscription.Dispose();
                }
            }
        }

        #endregion
    }
}
